package org.example;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;

public class ImageProcessingApp extends JFrame {
    private CustomPanel[] panels = new CustomPanel[4];
    private BufferedImage[] originalImages = new BufferedImage[4];
    private int imageCount = 0;

    public ImageProcessingApp() {
        setTitle("图像处理软件");
        setSize(1000, 700);
        setDefaultCloseOperation(EXIT_ON_CLOSE);

        // 创建侧边栏
        JPanel sidebar = new JPanel();
        sidebar.setPreferredSize(new Dimension(200, 700));
        sidebar.setLayout(new GridLayout(0, 1, 10, 10)); // 使用网格布局
        sidebar.setBackground(Color.DARK_GRAY); // 设置背景颜色
        sidebar.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); // 设置内边距



        // 添加按钮到侧边栏
        JButton openButton = createStyledButton("打开图片","/icon/openFile.png");
        JButton resetButton = createStyledButton("重置","/icon/reset.png");
        JButton saveButton = createStyledButton("保存图片","/icon/save.png");
        JButton rotateButton = createStyledButton("旋转","/icon/rotate.png");
        JButton cropButton = createStyledButton("裁剪","/icon/crop.png");
        JButton translateButton = createStyledButton("平移","/icon/translate.png");
        JButton clearButton = createStyledButton("清除","/icon/clean.png");

        // 添加按钮点击事件
        openButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                JFileChooser fileChooser = new JFileChooser();
                fileChooser.setMultiSelectionEnabled(true); // 设置允许多选
                int result = fileChooser.showOpenDialog(ImageProcessingApp.this);
                if (result == JFileChooser.APPROVE_OPTION) {
                    File[] selectedFiles = fileChooser.getSelectedFiles();
                    for (File file : selectedFiles) {
                        if (imageCount < 4) {
                            try {
                                // 加载图像并显示
                                originalImages[imageCount] = ImageIO.read(file);
                                BufferedImage scaledImage = scaleImageToFit(originalImages[imageCount], panels[imageCount].getWidth(), panels[imageCount].getHeight());
                                panels[imageCount].setImage(scaledImage);
                                panels[imageCount].setImageFileName(file.getName()); // 保存文件名
                                imageCount++;
                            } catch (Exception ex) {
                                ex.printStackTrace();
                            }
                        } else {
                            JOptionPane.showMessageDialog(ImageProcessingApp.this, "最多只能同时打开4个文件。", "警告", JOptionPane.WARNING_MESSAGE);
                            break;
                        }
                    }
                }
            }
        });

        resetButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                for (int i = 0; i < imageCount; i++) {
                    if (originalImages[i] != null) {
                        BufferedImage scaledImage = scaleImageToFit(originalImages[i], panels[i].getWidth(), panels[i].getHeight());
                        panels[i].setImage(scaledImage);
                        panels[i].resetTransforms();
                    }
                }
            }
        });

        saveButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                for (int i = 0; i < imageCount; i++) {
                    if (panels[i].getImage() != null) {
                        JFileChooser fileChooser = new JFileChooser();
                        String originalFileName = panels[i].getImageFileName();
                        String newFileName = originalFileName.substring(0, originalFileName.lastIndexOf('.')) + "_update.png";
                        fileChooser.setSelectedFile(new File(newFileName));
                        int result = fileChooser.showSaveDialog(ImageProcessingApp.this);
                        if (result == JFileChooser.APPROVE_OPTION) {
                            File file = fileChooser.getSelectedFile();
                            try {
                                panels[i].saveTransformedImage(file);
                            } catch (IOException ex) {
                                ex.printStackTrace();
                            }
                        }
                    }
                }
            }
        });


/*        saveButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                for (int i = 0; i < imageCount; i++) {
                    if (panels[i].getImage() != null) {
                        JFileChooser fileChooser = new JFileChooser();
                        String originalFileName = panels[i].getImageFileName();
                        String newFileName = originalFileName.substring(0, originalFileName.lastIndexOf('.')) + "_update.png";
                        fileChooser.setSelectedFile(new File(newFileName));
                        int result = fileChooser.showSaveDialog(ImageProcessingApp.this);
                        if (result == JFileChooser.APPROVE_OPTION) {
                            File file = fileChooser.getSelectedFile();
                            try {
                                BufferedImage transformedImage = panels[i].getTransformedImage();
                                ImageIO.write(transformedImage, "png", file);
                            } catch (IOException ex) {
                                ex.printStackTrace();
                            }
                        }
                    }
                }
            }
        });*/

        rotateButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                setPanelsMode(CustomPanel.Mode.ROTATE);

            }
        });

        cropButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                for (int i = 0; i < imageCount; i++) {
                    panels[i].setMode(CustomPanel.Mode.CROP);
                }
            }
        });

        translateButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                for (int i = 0; i < imageCount; i++) {
                    panels[i].setMode(CustomPanel.Mode.TRANSLATE);
                }
            }
        });

        clearButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                for (int i = 0; i < imageCount; i++) {
                    panels[i].clearImage();
                }
                imageCount = 0; // 重置图片计数
            }
        });

        // 将按钮添加到侧边栏
        sidebar.add(openButton);
        sidebar.add(resetButton);
        sidebar.add(saveButton);
        sidebar.add(rotateButton);
        sidebar.add(cropButton);
        sidebar.add(translateButton);
        sidebar.add(
                clearButton);

        // 创建主区域
        JPanel mainPanel = new JPanel();
        mainPanel.setLayout(new GridLayout(2, 2, 5, 5)); // 创建2x2网格布局并设置间距
        mainPanel.setBackground(Color.LIGHT_GRAY); // 设置背景颜色
        mainPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); // 设置内边距

        for (int i = 0; i < 4; i++) {
            panels[i] = new CustomPanel();
            panels[i].setBorder(BorderFactory.createLineBorder(Color.GRAY, 1)); // 为每个面板添加边框
            mainPanel.add(panels[i]);
        }

        // 将侧边栏和主区域添加到窗口
        getContentPane().add(sidebar, BorderLayout.WEST);
        getContentPane().add(mainPanel, BorderLayout.CENTER);

        setVisible(true);
    }

    private void setPanelsMode(CustomPanel.Mode mode) {
        for (int i = 0; i < imageCount; i++) {
            panels[i].setMode(mode);
        }
    }

    private JButton createStyledButton(String text,String iconPath) {

        URL resource = getClass().getResource(iconPath);
        ImageIcon buttonIcon = new ImageIcon(resource);

        JButton button = new JButton(text,buttonIcon);
        button.setFocusPainted(false);
        button.setBackground(Color.GRAY);
        button.setForeground(Color.WHITE);
        button.setFont(new Font("微软雅黑", Font.PLAIN, 14)); // 使用支持中文的字体
        button.setBorder(BorderFactory.createCompoundBorder(
                BorderFactory.createLineBorder(Color.DARK_GRAY, 1),
                BorderFactory.createEmptyBorder(10, 20, 10, 20)
        ));
        return button;
    }

    private BufferedImage scaleImageToFit(BufferedImage originalImage, int maxWidth, int maxHeight) {
        double scaleX = (double) maxWidth / originalImage.getWidth();
        double scaleY = (double) maxHeight / originalImage.getHeight();
        double scale = Math.min(scaleX, scaleY);

        int width = (int) (originalImage.getWidth() * scale);
        int height = (int) (originalImage.getHeight() * scale);

        BufferedImage scaledImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
        Graphics2D g2d = scaledImage.createGraphics();
        g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
        g2d.drawImage(originalImage, 0, 0, width, height, null);
        g2d.dispose();

        return scaledImage;
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> new ImageProcessingApp());
    }
}



class CustomPanel extends JPanel {
    public enum Mode { ROTATE, CROP, TRANSLATE }

    private BufferedImage image;
    private String imageFileName;
    private Mode mode = Mode.TRANSLATE;
    private double scale = 1.0;
    private double rotationAngle = 0;
    private double translateX = 0;
    private double translateY = 0;
    private Point startPoint = null;
    private Point endPoint = null;

    public CustomPanel() {
        addMouseListener(new MouseAdapter() {
            @Override
            public void mousePressed(MouseEvent e) {
                startPoint = e.getPoint();
                endPoint = null;
            }

            @Override
            public void mouseReleased(MouseEvent e) {
                if (mode == Mode.CROP && startPoint != null && endPoint != null) {
                    cropImage();
                }
                startPoint = null;
                endPoint = null;
                repaint();
            }
        });

        addMouseMotionListener(new MouseMotionAdapter() {
            @Override
            public void mouseDragged(MouseEvent e) {
                endPoint = e.getPoint();
                if (mode == Mode.TRANSLATE && startPoint != null) {
                    translateX += e.getX() - startPoint.x;
                    translateY += e.getY() - startPoint.y;
                    startPoint = e.getPoint();
                }
                else if (mode == Mode.ROTATE   && startPoint != null){
                    rotationAngle += Math.toRadians(1); // 调整旋转角度增量
                }
                repaint();
            }
        });

        addMouseWheelListener(new MouseWheelListener() {
            @Override
            public void mouseWheelMoved(MouseWheelEvent e) {
                double delta = 0.05 * e.getPreciseWheelRotation();
                scale += delta;
                scale = Math.max(0.1, scale);
                repaint();
            }
        });
    }

    public void setImage(BufferedImage image) {
        this.image = image;
        repaint();
    }

    public BufferedImage getImage() {
        return image;
    }

    public void setImageFileName(String fileName) {
        this.imageFileName = fileName;
    }

    public String getImageFileName() {
        return imageFileName;
    }

    public BufferedImage getTransformedImage() {
        if (image != null) {
            int width = image.getWidth();
            int height = image.getHeight();

            BufferedImage transformedImage = new BufferedImage(width, height, image.getType());
            Graphics2D g2d = transformedImage.createGraphics();
            AffineTransform transform = new AffineTransform();
            transform.translate(width / 2, height / 2);
            transform.rotate(rotationAngle);
            transform.scale(scale, scale);
            transform.translate(-width / 2, -height / 2);
            transform.translate(translateX, translateY);
            g2d.drawImage(image, transform, null);
            g2d.dispose();
            return transformedImage;
        }
        return null;
    }

    public void resetTransforms() {
        scale = 1.0;
        translateX = 0;
        translateY = 0;
        rotationAngle = 0;
    }

    public void setMode(Mode mode) {
        this.mode = mode;
    }

    public void clearImage() {
        image = null;
        repaint();
    }

    private void cropImage() {
        if (startPoint != null && endPoint != null && image != null) {
            int x = (int) Math.min(startPoint.x / scale - translateX, endPoint.x / scale - translateX);
            int y = (int) Math.min(startPoint.y / scale - translateY, endPoint.y / scale - translateY);
            int width = (int) Math.abs(startPoint.x / scale - endPoint.x / scale);
            int height = (int) Math.abs(startPoint.y / scale - endPoint.y / scale);

            // Ensure the crop rectangle is within the bounds of the image
            x = Math.max(0, x);
            y = Math.max(0, y);
            width = Math.min(image.getWidth() - x, width);
            height = Math.min(image.getHeight() - y, height);

            if (width > 0 && height > 0) {
                image = image.getSubimage(x, y, width, height);
            }
        }
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        if (image != null) {
            Graphics2D g2d = (Graphics2D) g.create();
            g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
            g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

            AffineTransform transform = new AffineTransform();
            transform.translate(translateX, translateY);
            transform.scale(scale, scale);
            transform.rotate(rotationAngle, image.getWidth() / 2.0, image.getHeight() / 2.0);

            int x = (getWidth() - image.getWidth()) / 2;
            int y = (getHeight() - image.getHeight()) / 2;

            g2d.drawImage(image, transform, null);

            if (mode == Mode.CROP && startPoint != null && endPoint != null) {
                int cropX = (int) Math.min(startPoint.x, endPoint.x);
                int cropY = (int) Math.min(startPoint.y, endPoint.y);
                int cropWidth = (int) Math.abs(startPoint.x - endPoint.x);
                int cropHeight = (int) Math.abs(startPoint.y - endPoint.y);

                g2d.setColor(Color.RED);
                g2d.setStroke(new BasicStroke(2));
                g2d.drawRect(cropX, cropY, cropWidth, cropHeight);
            }

            g2d.dispose();
        }
    }
    public void saveTransformedImage(File file) throws IOException {
        int width = getWidth();
        int height = getHeight();
        BufferedImage transformedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
        Graphics2D g2d = transformedImage.createGraphics();
        paint(g2d);
        g2d.dispose();
        ImageIO.write(transformedImage, "png", file);
    }
}



